float4x4 World;
float4x4 View;
float4x4 Projection;

// ***** Light properties *****
float3 LightPosition;
float3 EyePos;

struct VS_INPUT
{
    float4 position            : POSITION0;
    float2 texCoord            : TEXCOORD0;
    float3 normal            : NORMAL0;    
    float3 binormal            : BINORMAL0;
    float3 tangent            : TANGENT0;
};

struct VS_OUTPUT
{
    float4 position : POSITION0;
    float2 texCoord : TEXCOORD0;
    float3 posToLight : TEXCOORD1;
    float3 posToEye : TEXCOORD2;
    float3x3 tangentToWorld    : TEXCOORD3;
};

VS_OUTPUT main( VS_INPUT input )
{
    VS_OUTPUT output;
    
    // transform the position into projection space
    float4 worldSpacePos = mul(input.position, World);
    output.position = mul(worldSpacePos, View);
    output.position = mul(output.position, Projection);
    
    // calculate the light direction ( from the surface to the light ), which is not
    // normalized and is in world space
    output.posToLight = LightPosition - worldSpacePos;
        
    // similarly, calculate the view direction, from the eye to the surface.  not
    // normalized, in world space.  
    output.posToEye = EyePos - worldSpacePos;    
    
    // calculate tangent space to world space matrix using the world space tangent,
    // binormal, and normal as basis vectors.  the pixel shader will normalize these
    // in case the world matrix has scaling.
    output.tangentToWorld[0] = mul(input.tangent,    World);
    output.tangentToWorld[1] = mul(input.binormal,    World);
    output.tangentToWorld[2] = mul(input.normal,    World);
    
    // pass the texture coordinate through without additional processing
    output.texCoord = input.texCoord;
    
    return output;
}